package handlers

import (
	"data_service/models"
	"data_service/server"
	"data_service/utils"
	"fmt"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 初始化管理员服务
var adminService *server.AdminService

// InitAdminService 初始化管理员服务
func InitAdminService(db *gorm.DB) {
	adminService = server.NewAdminServiceWithDB(db)
}

// ==================== 用户管理接口 ====================

// GetUserList 获取用户列表（管理员）
func GetUserList(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_USER_LIST] 收到获取用户列表请求 - IP: %s\n", c.ClientIP())

	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	keyword := c.Query("keyword")
	role := c.Query("role")
	status := c.Query("status")

	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}

	// 获取用户列表
	users, total, err := adminService.GetUserList(page, pageSize, keyword, role, status)
	if err != nil {
		utils.Logger.Error().Err(err).Msg("获取用户列表失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_USER_LIST_FAILED",
			"message": "获取用户列表失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	// 清除敏感信息
	for i := range users {
		users[i].Password = ""
	}

	fmt.Printf("[ADMIN_GET_USER_LIST] 获取成功 - 总数: %d, 当前页: %d\n", total, page)

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取用户列表成功",
		"data": gin.H{
			"users":      users,
			"total":      total,
			"page":       page,
			"page_size":  pageSize,
			"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
		},
	})
}

// UpdateUserRole 更新用户角色
func UpdateUserRole(c *gin.Context) {
	fmt.Printf("[ADMIN_UPDATE_USER_ROLE] 收到更新用户角色请求 - IP: %s\n", c.ClientIP())

	userIDStr := c.Param("id")
	userID, err := strconv.ParseUint(userIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_USER_ID",
			"message": "用户ID格式错误",
			"data":    gin.H{"details": "用户ID必须是数字"},
		})
		return
	}

	var req struct {
		Role string `json:"role" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_JSON_FORMAT",
			"message": "请求参数格式错误",
			"data":    gin.H{"details": "请检查JSON格式是否正确"},
		})
		return
	}

	// 验证角色（使用常量）
	if !models.IsValidRole(req.Role) {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_ROLE",
			"message": "无效的用户角色",
			"data":    gin.H{"details": "角色必须是 user、moderator 或 admin"},
		})
		return
	}

	// 更新用户角色
	if err := adminService.UpdateUserRole(uint(userID), req.Role); err != nil {
		utils.Logger.Error().Err(err).Uint("user_id", uint(userID)).Str("role", req.Role).Msg("更新用户角色失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "UPDATE_ROLE_FAILED",
			"message": "更新用户角色失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	utils.Logger.Info().Uint("user_id", uint(userID)).Str("role", req.Role).Msg("用户角色更新成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "用户角色更新成功",
		"data":    gin.H{"role": req.Role},
	})
}

// BanUser 封禁/解封用户
func BanUser(c *gin.Context) {
	fmt.Printf("[ADMIN_BAN_USER] 收到封禁用户请求 - IP: %s\n", c.ClientIP())

	userIDStr := c.Param("id")
	userID, err := strconv.ParseUint(userIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_USER_ID",
			"message": "用户ID格式错误",
			"data":    gin.H{"details": "用户ID必须是数字"},
		})
		return
	}

	var req struct {
		Status string `json:"status" binding:"required"`
		Reason string `json:"reason"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_JSON_FORMAT",
			"message": "请求参数格式错误",
			"data":    gin.H{"details": "请检查JSON格式是否正确"},
		})
		return
	}

	// 验证状态（使用常量）
	if !models.IsValidStatus(req.Status) {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_STATUS",
			"message": "无效的用户状态",
			"data":    gin.H{"details": "状态必须是 active 或 banned"},
		})
		return
	}

	// 更新用户状态
	if err := adminService.UpdateUserStatus(uint(userID), req.Status, req.Reason); err != nil {
		utils.Logger.Error().Err(err).Uint("user_id", uint(userID)).Str("status", req.Status).Msg("更新用户状态失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "UPDATE_STATUS_FAILED",
			"message": "更新用户状态失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	action := "解封"
	if req.Status == models.StatusBanned {
		action = "封禁"
	}

	utils.Logger.Info().Uint("user_id", uint(userID)).Str("status", req.Status).Str("reason", req.Reason).Msg("用户状态更新成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": fmt.Sprintf("用户%s成功", action),
		"data":    gin.H{"status": req.Status, "reason": req.Reason},
	})
}

// GetUserStats 获取用户统计信息
func GetUserStats(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_USER_STATS] 收到获取用户统计请求 - IP: %s\n", c.ClientIP())

	stats, err := adminService.GetUserStats()
	if err != nil {
		utils.Logger.Error().Err(err).Msg("获取用户统计失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_USER_STATS_FAILED",
			"message": "获取用户统计失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	fmt.Printf("[ADMIN_GET_USER_STATS] 获取成功 - 总用户: %d, 活跃用户: %d\n", stats.TotalUsers, stats.ActiveUsers)

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取用户统计成功",
		"data":    stats,
	})
}

// ==================== 公告管理接口 ====================

// GetAnnouncementList 获取公告列表
func GetAnnouncementList(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_ANNOUNCEMENT_LIST] 收到获取公告列表请求 - IP: %s\n", c.ClientIP())

	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	status := c.Query("status")
	typeFilter := c.Query("type")

	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}

	// 获取公告列表
	announcements, total, err := adminService.GetAnnouncementList(page, pageSize, status, typeFilter)
	if err != nil {
		utils.Logger.Error().Err(err).Msg("获取公告列表失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_ANNOUNCEMENT_LIST_FAILED",
			"message": "获取公告列表失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	fmt.Printf("[ADMIN_GET_ANNOUNCEMENT_LIST] 获取成功 - 总数: %d, 当前页: %d\n", total, page)

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取公告列表成功",
		"data": gin.H{
			"announcements": announcements,
			"total":         total,
			"page":          page,
			"page_size":     pageSize,
			"total_page":    (total + int64(pageSize) - 1) / int64(pageSize),
		},
	})
}

// CreateAnnouncement 创建公告
func CreateAnnouncement(c *gin.Context) {
	fmt.Printf("[ADMIN_CREATE_ANNOUNCEMENT] 收到创建公告请求 - IP: %s\n", c.ClientIP())

	var req struct {
		Title      string `json:"title" binding:"required"`
		Content    string `json:"content" binding:"required"`
		Type       string `json:"type"`
		Priority   int    `json:"priority"`
		AuthorID   uint   `json:"author_id" binding:"required"`
		AuthorName string `json:"author_name" binding:"required"`
		ExpireTime string `json:"expire_time"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_JSON_FORMAT",
			"message": "请求参数格式错误",
			"data":    gin.H{"details": "请检查JSON格式是否正确"},
		})
		return
	}

	// 设置默认值
	if req.Type == "" {
		req.Type = "info"
	}
	if req.Priority < 0 || req.Priority > 2 {
		req.Priority = 0
	}

	// 解析过期时间
	var expireTime *time.Time
	if req.ExpireTime != "" {
		if parsedTime, err := time.Parse(time.RFC3339, req.ExpireTime); err == nil {
			expireTime = &parsedTime
		}
	}

	// 创建公告
	announcement := &models.Announcement{
		Title:      req.Title,
		Content:    req.Content,
		Type:       req.Type,
		Priority:   req.Priority,
		Status:     "draft",
		AuthorID:   req.AuthorID,
		AuthorName: req.AuthorName,
		ExpireTime: expireTime,
	}

	if err := adminService.CreateAnnouncement(announcement); err != nil {
		utils.Logger.Error().Err(err).Str("title", req.Title).Msg("创建公告失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "CREATE_ANNOUNCEMENT_FAILED",
			"message": "创建公告失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	utils.Logger.Info().Uint("announcement_id", announcement.ID).Str("title", req.Title).Msg("公告创建成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "公告创建成功",
		"data":    announcement,
	})
}

// PublishAnnouncement 发布公告
func PublishAnnouncement(c *gin.Context) {
	fmt.Printf("[ADMIN_PUBLISH_ANNOUNCEMENT] 收到发布公告请求 - IP: %s\n", c.ClientIP())

	announcementIDStr := c.Param("id")
	announcementID, err := strconv.ParseUint(announcementIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_ANNOUNCEMENT_ID",
			"message": "公告ID格式错误",
			"data":    gin.H{"details": "公告ID必须是数字"},
		})
		return
	}

	// 发布公告
	if err := adminService.PublishAnnouncement(uint(announcementID)); err != nil {
		utils.Logger.Error().Err(err).Uint("announcement_id", uint(announcementID)).Msg("发布公告失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "PUBLISH_ANNOUNCEMENT_FAILED",
			"message": "发布公告失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	utils.Logger.Info().Uint("announcement_id", uint(announcementID)).Msg("公告发布成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "公告发布成功",
		"data":    gin.H{"status": "published"},
	})
}

// UpdateAnnouncement 更新公告
func UpdateAnnouncement(c *gin.Context) {
	fmt.Printf("[ADMIN_UPDATE_ANNOUNCEMENT] 收到更新公告请求 - IP: %s\n", c.ClientIP())

	announcementIDStr := c.Param("id")
	announcementID, err := strconv.ParseUint(announcementIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_ANNOUNCEMENT_ID",
			"message": "公告ID格式错误",
			"data":    gin.H{"details": "公告ID必须是数字"},
		})
		return
	}

	var req struct {
		Title      string `json:"title"`
		Content    string `json:"content"`
		Type       string `json:"type"`
		Priority   int    `json:"priority"`
		Status     string `json:"status"`
		ExpireTime string `json:"expire_time"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_JSON_FORMAT",
			"message": "请求参数格式错误",
			"data":    gin.H{"details": "请检查JSON格式是否正确"},
		})
		return
	}

	// 解析过期时间
	var expireTime *time.Time
	if req.ExpireTime != "" {
		if parsedTime, err := time.Parse(time.RFC3339, req.ExpireTime); err == nil {
			expireTime = &parsedTime
		}
	}

	// 更新公告
	updateData := make(map[string]interface{})
	if req.Title != "" {
		updateData["title"] = req.Title
	}
	if req.Content != "" {
		updateData["content"] = req.Content
	}
	if req.Type != "" {
		updateData["type"] = req.Type
	}
	if req.Priority >= 0 && req.Priority <= 2 {
		updateData["priority"] = req.Priority
	}
	if req.Status != "" {
		updateData["status"] = req.Status
	}
	if expireTime != nil {
		updateData["expire_time"] = expireTime
	}

	if err := adminService.UpdateAnnouncement(uint(announcementID), updateData); err != nil {
		utils.Logger.Error().Err(err).Uint("announcement_id", uint(announcementID)).Msg("更新公告失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "UPDATE_ANNOUNCEMENT_FAILED",
			"message": "更新公告失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	utils.Logger.Info().Uint("announcement_id", uint(announcementID)).Msg("公告更新成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "公告更新成功",
		"data":    updateData,
	})
}

// DeleteAnnouncement 删除公告
func DeleteAnnouncement(c *gin.Context) {
	fmt.Printf("[ADMIN_DELETE_ANNOUNCEMENT] 收到删除公告请求 - IP: %s\n", c.ClientIP())

	announcementIDStr := c.Param("id")
	announcementID, err := strconv.ParseUint(announcementIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_ANNOUNCEMENT_ID",
			"message": "公告ID格式错误",
			"data":    gin.H{"details": "公告ID必须是数字"},
		})
		return
	}

	// 删除公告
	if err := adminService.DeleteAnnouncement(uint(announcementID)); err != nil {
		utils.Logger.Error().Err(err).Uint("announcement_id", uint(announcementID)).Msg("删除公告失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "DELETE_ANNOUNCEMENT_FAILED",
			"message": "删除公告失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	utils.Logger.Info().Uint("announcement_id", uint(announcementID)).Msg("公告删除成功")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "公告删除成功",
		"data":    gin.H{"deleted": true},
	})
}

// ==================== 系统管理接口 ====================

// GetSystemLogs 获取系统日志
func GetSystemLogs(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_SYSTEM_LOGS] 收到获取系统日志请求 - IP: %s\n", c.ClientIP())

	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "50"))
	action := c.Query("action")
	userID := c.Query("user_id")

	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 200 {
		pageSize = 50
	}

	// 解析用户ID
	var userIDUint uint
	if userID != "" {
		if parsed, err := strconv.ParseUint(userID, 10, 32); err == nil {
			userIDUint = uint(parsed)
		}
	}

	// 获取系统日志
	logs, total, err := adminService.GetSystemLogs(page, pageSize, action, userIDUint)
	if err != nil {
		utils.Logger.Error().Err(err).Msg("获取系统日志失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_SYSTEM_LOGS_FAILED",
			"message": "获取系统日志失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	fmt.Printf("[ADMIN_GET_SYSTEM_LOGS] 获取成功 - 总数: %d, 当前页: %d\n", total, page)

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取系统日志成功",
		"data": gin.H{
			"logs":       logs,
			"total":      total,
			"page":       page,
			"page_size":  pageSize,
			"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
		},
	})
}

// GetSystemInfo 获取系统信息
func GetSystemInfo(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_SYSTEM_INFO] 收到获取系统信息请求 - IP: %s\n", c.ClientIP())

	info, err := adminService.GetSystemInfo()
	if err != nil {
		utils.Logger.Error().Err(err).Msg("获取系统信息失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_SYSTEM_INFO_FAILED",
			"message": "获取系统信息失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	fmt.Printf("[ADMIN_GET_SYSTEM_INFO] 获取成功\n")
	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取系统信息成功",
		"data":    info,
	})
}

// ==================== 权限管理接口 ====================

// GetRoles 获取角色列表（简化版，使用常量）
func GetRoles(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_ROLES] 收到获取角色列表请求 - IP: %s\n", c.ClientIP())

	// 从常量中获取角色描述
	roles := models.GetRoleDescriptions()

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取角色列表成功",
		"data":    roles,
	})
}

// GetUserRole 获取用户角色信息（简化版）
func GetUserRole(c *gin.Context) {
	fmt.Printf("[ADMIN_GET_USER_ROLE] 收到获取用户角色请求 - IP: %s\n", c.ClientIP())

	userIDStr := c.Param("id")
	userID, err := strconv.ParseUint(userIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    "INVALID_USER_ID",
			"message": "用户ID格式错误",
			"data":    gin.H{"details": "用户ID必须是数字"},
		})
		return
	}

	// 直接通过用户ID获取用户信息
	user, err := adminService.GetUserByID(uint(userID))
	if err != nil {
		utils.Logger.Error().Err(err).Uint("user_id", uint(userID)).Msg("获取用户信息失败")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    "GET_USER_FAILED",
			"message": "获取用户信息失败",
			"data":    gin.H{"details": "服务器内部错误，请稍后重试"},
		})
		return
	}

	// 返回用户角色信息
	roleInfo := gin.H{
		"user_id": user.ID,
		"role":    user.Role,
		"status":  user.Status,
		"name":    user.Name,
		"email":   user.Email,
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    "SUCCESS",
		"message": "获取用户角色成功",
		"data":    roleInfo,
	})
}
